package de.tudresden.inf.ggp.basicplayer;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.map.ReferenceMap;
import org.eclipse.palamedes.gdl.core.model.IGameState;
import org.eclipse.palamedes.gdl.core.model.IMove;

public class CListStates {

	Map<IGameState,CDataState> StateMap;
	
	public CListStates(){
		StateMap=new ReferenceMap();
		StateMap.clear();
	}

	public void addNewStates(IGameState TheState, CDataState DataState){
		this.StateMap.put(TheState, DataState);
	}
	
	public int getStatesLength(){
		return StateMap.size();
	} 
	
	public boolean containState(IGameState TheState){
		return this.StateMap.containsKey(TheState);
	}
	
	public boolean addStateActionVisit(IGameState TheState,  IMove Act,  int N){
		return this.StateMap.get(TheState).addActionVisit(Act, N);
	} 
	
	public boolean addStateActionValue(IGameState TheState,  IMove Act,  int Value){
		return this.StateMap.get(TheState).addActionValue(Act, Value);
	} 
	
	public IMove getBestAction1(IGameState TheState, int C){
		return this.StateMap.get(TheState).chooseAction1(C);
	} 
	
	public IMove getBestAction2(IGameState TheState, CListAction ListActionHistory,int C){
		return this.StateMap.get(TheState).chooseAction2(ListActionHistory, C);
	} 
	
	public CDataState getDataState(IGameState TheState){
		return this.StateMap.get(TheState);
	}
	
	public  boolean saveToFile(String FileName){
		File file=new File("source//de//tudresden//inf//ggp//basicplayer//"+FileName);
		try{
			ObjectOutputStream objOutputStream=new ObjectOutputStream(new FileOutputStream(file));
			objOutputStream.writeObject(StateMap);
			objOutputStream.close();
		}catch(IOException e){
			e.printStackTrace();
			return false;
		}
		return true;
	}
	
	public Map loadFromFile(String FileName) throws Exception{
		File file=new File("source//de//tudresden//inf//ggp//basicplayer//"+FileName);
		if(!file.exists()){
			throw new FileNotFoundException();
		}
		Map<IGameState,CDataState> StateMapTemp=null;
		try{
			ObjectInputStream objInputStream=new ObjectInputStream(new FileInputStream(file));
			StateMapTemp=(Map<IGameState, CDataState>) objInputStream.readObject();
			objInputStream.close();
		}catch(IOException e){
			e.printStackTrace();
		}
		return StateMapTemp;
	}
}
/**
 * Field 
o  StateMap: List of IGameState and CdataState. Use ReferenceMap <IGameState, 
CDataState> 
Constructor 
o  Public ListStates(): create and clear the StateMap 
Method /
o  Public void addNewStates(TheState: IGameState, DataState: CDataState): add 
<TheState, DataState> to the StateMap. 
o  Public boolean containState(TheState: IGameState): return true if TheState exist in 
StateMap, return false if TheState does not exist in StateMap 
o  Public boolean addStateActionVisit(TheState:IGameState, Act: IMove, N: integer) 
  Search for TheState in StateMap, get its DataState.  
  Then use CDataState.addActionVisit(Act, N) to add N to the NVisit of the action 
Act 
o  Public boolean addStateActionValue(TheState:IGameState, Act: IMove, Value: integer) 
  Search for TheState in StateMap, get its DataState.  
  Use CDataState.addActionValue(Act, Value) to add Value to the TotalValue of the 
action Act. 
o  Public IMove getBestAction1(TheState: IGameState, C: integer) 
  Search for TheState in StateMap, get its DataState.  
  Use CDataState.chooseAction1(C) to choose the best action of the state TheState 
o  Public IMove getBestAction2(TheState: IGameState, ListActionHistory: CListAction, C: 
integer) 
  Search for TheState in StateMap, get its DataState.  
  Use CDataState.chooseAction2(ListActionHistory, C) to choose the best action of 
the state TheState 
 */